package controller

import (
	"context"
	"strings"

	tableUser "gitee.com/klein-x/biz/model/mysql/table/user"
	"gitee.com/klein-x/biz/module/db/mysql"
	redis "gitee.com/klein-x/biz/module/db/redis/captcha"
	"gitee.com/klein-x/biz/xutils"
	"github.com/cloudwego/hertz/pkg/common/hlog"
)

const (
	USER_DB_ERR          = 9900
	USER_INVAILD_USER_ID = 4001
	USER_INVAILD_CAPTCHA = 4002
	USER_MAKE_UUID_ERROR = 4003
	USER_ALREADY_EXITS   = 4004
	USER_PHONE_ID_ERROR  = 4005
	USER_PASSWORD_ERROR  = 4006
)

func GetUser(ctx context.Context, uid string) (*UserInfo, error) {
	tableUser, err := tableUser.UserGetByID(uid)
	if err != nil {
		return nil, xutils.Error(USER_DB_ERR, err)
	}
	if tableUser == nil {
		return nil, xutils.Error(USER_INVAILD_USER_ID, "无效的用户ID")
	}

	uInfo := UserInfo{}

	uInfo.Mobile = tableUser.Mobile
	uInfo.Name = tableUser.Name
	return &uInfo, nil
}

func Register(ctx context.Context, phone string, password string, captcha string) error {
	// 1. 检查手机验证码
	if err := redis.ValidateCaptcha(ctx, phone, captcha); err != nil {
		hlog.CtxErrorf(ctx, "验证码验证失败,%v", err)
		return xutils.Error(USER_INVAILD_CAPTCHA, "验证码验证失败")
	}

	// 2. 检查手机号是否已注册
	user, err := tableUser.UserGetByMobileWithDeleted(phone)
	if err != nil {
		return xutils.Error(USER_DB_ERR, err)
	}

	if user == nil {
		newUser := tableUser.User{}
		uid, err := xutils.RandomUUID()
		if err != nil {
			return xutils.Error(USER_MAKE_UUID_ERROR, "生成UUID失败")
		}
		newUser.UUID = uid
		newUser.Mobile = phone
		newUser.Name = builderUserNameForPhone(phone)
		newUser.Password = password
		newUser.Type = "0"
		return tableUser.UserInsert(newUser)
	} else {
		if user.DeletedAt.Time.IsZero() {
			return xutils.Error(USER_ALREADY_EXITS, "用户已注册")
		}
		//  已经软删除的用户
		tx := mysql.BeginTran()
		if tx.Error != nil {
			return xutils.Error(USER_DB_ERR, tx.Error.Error())
		}
		if err := tableUser.UserRestoreById(user.UUID); err != nil {
			tx.Rollback()
			return xutils.Error(USER_DB_ERR, err)
		}

		if err := tableUser.UserUpdatePasswordById(user.UUID, password); err != nil {
			tx.Rollback()
			return xutils.Error(USER_DB_ERR, err)
		}
		//TODO:可能还要恢复其他被软删除的库表
		if tx := tx.Commit(); tx.Error != nil {
			return xutils.Error(USER_DB_ERR, tx.Error.Error())
		}
		return nil
	}
}

func builderUserNameForPhone(phone string) string {
	var strBuilder strings.Builder

	strBuilder.WriteString("逢考必过")
	strBuilder.WriteString(phone[7:])
	return strBuilder.String()
}

func LoginWithPassword(phone string, password string) (string, error) {
	listUser, err := tableUser.UserGetByMobile(phone)
	if err != nil {
		return "", xutils.Error(USER_DB_ERR, err)
	}

	if listUser == nil {
		return "", xutils.Error(USER_PHONE_ID_ERROR, "无效的手机号")
	}
	if listUser.Password != password {
		return "", xutils.Error(USER_PASSWORD_ERROR, "密码错误")
	}

	return listUser.UUID, nil
}

func LoginWithCaptcha(ctx context.Context, phone string, captcha string) (string, error) {
	if err := redis.ValidateCaptcha(ctx, phone, captcha); err != nil {
		hlog.CtxErrorf(ctx, "检查验证码失败,%v", err)
		return "", xutils.Error(USER_INVAILD_CAPTCHA, "验证码验证失败")
	}

	User, err := tableUser.UserGetByMobile(phone)
	if err != nil {
		return "", xutils.Error(USER_DB_ERR, err)
	}

	// note: 2025年2月22 需求更改, 验证码登录时遇到未注册的直接登录再注册
	// if User == nil {
	// 	return "", ctrl.MakeError(USER_PHONE_ID_ERROR, "无效的手机号")
	// }
	if User == nil {
		user, err := tableUser.UserGetByMobileWithDeleted(phone)
		if err != nil {
			return "", xutils.Error(USER_DB_ERR, err)
		}

		if user == nil {
			newUser := tableUser.User{}
			uid, err := xutils.RandomUUID()
			if err != nil {
				return "", xutils.Error(USER_MAKE_UUID_ERROR, "生成UUID失败")
			}
			pass, err := xutils.RandomString(16)
			if err != nil {
				return "", xutils.Error(USER_MAKE_UUID_ERROR, "生成UUID失败")
			}
			newUser.UUID = uid
			newUser.Mobile = phone
			newUser.Name = builderUserNameForPhone(phone)
			newUser.Password = pass
			newUser.Type = "0"
			return newUser.UUID, tableUser.UserInsert(newUser)
		} else {
			if user.DeletedAt.Time.IsZero() {
				return "", xutils.Error(USER_ALREADY_EXITS, "用户已注册")
			}
			pass, err := xutils.RandomString(16)
			if err != nil {
				return "", xutils.Error(USER_MAKE_UUID_ERROR, "生成UUID失败")
			}
			//  已经软删除的用户
			tx := mysql.BeginTran()
			if tx.Error != nil {
				return "", xutils.Error(USER_DB_ERR, tx.Error.Error())
			}
			if err := tableUser.UserRestoreById(user.UUID); err != nil {
				tx.Rollback()
				return "", xutils.Error(USER_DB_ERR, err)
			}

			if err := tableUser.UserUpdatePasswordById(user.UUID, pass); err != nil {
				tx.Rollback()
				return "", xutils.Error(USER_DB_ERR, err)
			}
			//TODO:可能还要恢复其他被软删除的库表
			if tx := tx.Commit(); tx.Error != nil {
				return "", xutils.Error(USER_DB_ERR, tx.Error.Error())
			}
			return user.UUID, nil
		}
	}
	return User.UUID, nil
}

func UpdatePassword(ctx context.Context, phone string, password string, captcha string) error {
	// 1. 检查手机验证码
	if err := redis.ValidateCaptcha(ctx, phone, captcha); err != nil {
		hlog.CtxErrorf(ctx, "检查验证码失败,%v", err)
		return xutils.Error(USER_INVAILD_CAPTCHA, "验证码验证失败")
	}

	// 2. 查找用户
	User, err := tableUser.UserGetByMobile(phone)
	if err != nil {
		return xutils.Error(USER_DB_ERR, err)
	}

	if User == nil {
		return xutils.Error(USER_INVAILD_USER_ID, "无效的用户ID")
	}
	return tableUser.UserUpdatePasswordById(User.UUID, password)
}

func UpdateUsername(ctx context.Context, uid string, username string) error {
	user, err := tableUser.UserGetByID(uid)
	if err != nil {
		return xutils.Error(USER_DB_ERR, err)
	}
	if user == nil {
		return xutils.Error(USER_INVAILD_USER_ID, "无效的用户ID")
	}
	return tableUser.UserUpdateUsernameById(user.UUID, username)
}
